﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>ComObjQuery - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The ComObjQuery function queries a COM object for an interface or service." />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>ComObjQuery</h1>
<p>查询 COM 对象的接口或服务.</p>
<pre class="Syntax">InterfacePointer := <span class="func">ComObjQuery</span>(ComObject, <span class="optional">SID,</span> IID)</pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>ComObject</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#objects">对象</a>或<a href="../Concepts.htm#numbers">整数</a></p>
    <p>COM 包装器对象, 接口指针或一个具有 <code>Ptr</code> 属性的对象, 该属性返回一个接口指针.</p>
  </dd>

  <dt>IID</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>格式为 "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" 的接口标识符(GUID).</p>
  </dd>

  <dt>SID</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>与 IID 格式相同的服务标识符. 省略此参数时, 还要省略逗号.</p>
  </dd>

</dl>

<h2 id="Return_Value">返回值</h2>
<p>类型: <a href="ComObject.htm#Returns">ComObject</a></p>
<p>该函数返回一个类型为 VT_UNKNOWN(13) 的 COM 封装对象.</p>

<h2 id="Remarks">备注</h2>
<p>在此函数使用两个参数时, 它相当于 <a href="http://msdn.microsoft.com/en-us/library/ms682521.aspx">IUnknown::QueryInterface</a>. 如果同时指定了 SID 和 IID, 那么它会内部查询 <a href="http://msdn.microsoft.com/en-us/library/cc678965.aspx">IServiceProvider</a> 接口, 然后调用 <a href="http://msdn.microsoft.com/en-us/library/cc678966.aspx">IServiceProvider::QueryService</a>. 在两种形式中, 返回值为零或对被请求接口的指针. 通常, 在脚本结束时必须<a href="ObjAddRef.htm">释放</a>这种指针.</p>
<p><a href="ComCall.htm">ComCall</a> 可以用来调用原生接口方法.</p>

<h2 id="Related">相关</h2>
<p><a href="ComCall.htm">ComCall</a>, <a href="ComObjCreate.htm">ComObjCreate</a>, <a href="ComObjGet.htm">ComObjGet</a>, <a href="ComObjActive.htm">ComObjActive</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExClassName">
<p><a href="#ExClassName">#1</a>: 确定对象的类名.</p>
<pre>
obj := ComObjCreate("Scripting.Dictionary")

MsgBox "Interface name: " ComObjType(obj, "name")

IID_IProvideClassInfo := "{B196B283-BAB4-101A-B69C-00AA00341D07}"

<em>; 请求对象的 IProvideClassInfo 接口.</em>
try
    pci := ComObjQuery(obj, IID_IProvideClassInfo)
catch
{
    MsgBox "IProvideClassInfo interface not supported."
    return
}

<em>; 调用 GetClassInfo 来获取 ITypeInfo 接口的指针.</em>
ComCall(3, pci, "ptr*", ti := 0)

<em>; 封装 ti 以确保自动清理.</em>
ti := ComObject(13, ti)

<em>; 调用 GetDocumentation 来获取对象的完整类型名称.</em>
ComCall(12, ti, "int", -1, "ptr*", pname := 0, "ptr", 0, "ptr", 0, "ptr", 0)

<em>; 转换 BSTR 指针为可用的字符串.</em>
name := StrGet(pname, "UTF-16")

<em>; 清理.</em>
DllCall("oleaut32\SysFreeString", "ptr", pname)
pci := ti := ""

<em>; 显示类型名称!</em>
MsgBox "Class name: " name
</pre>
</div>

<div class="ex" id="ExIE">
<p><a href="#ExIE">#2</a>: 自动化现有的 Internet Explorer 窗口.</p>
<pre>
sURL := "https://www.autohotkey.com/boards/"
if WebBrowser := GetWebBrowser()
    WebBrowser.Navigate(sURL)
return

GetWebBrowser()
{
    <em>; 获取指向顶部 IE 窗口的文档对象的原始指针.</em>
    static msg := DllCall("RegisterWindowMessage", "Str", "WM_HTML_GETOBJECT")
    lResult := SendMessage(msg, 0, 0, "Internet Explorer_Server1", "ahk_class IEFrame")
    if !lResult
        return  <em>; 未找到 IE.</em>
    static IID_IHTMLDocument2 := GUID("{332C4425-26CB-11D0-B483-00C04FD90119}")
    static VT_UNKNOWN := 13
    DllCall("oleacc\ObjectFromLresult", "Ptr", lResult
        , "Ptr", IID_IHTMLDocument2, "Ptr", 0
        , "Ptr*", pdoc := ComObject(VT_UNKNOWN, 0))
    
    <em>; 查询 WebBrowserApp 服务. 在这种特殊情况中,
    ; SID 和 IID 相同, 但不总是如此.</em>
    static IID_IWebBrowserApp := "{0002DF05-0000-0000-C000-000000000046}"
    static SID_SWebBrowserApp := IID_IWebBrowserApp
    pweb := ComObjQuery(pdoc, SID_SWebBrowserApp, IID_IWebBrowserApp)
    
    <em>; Return the WebBrowser object as IDispatch for usability.
    ; This works only because IWebBrowserApp is derived from IDispatch.
    ; pweb will release its ptr automatically, so AddRef to counter that.</em>
    ObjAddRef(pweb.ptr)
    static VT_DISPATCH := 9
    return ComObject(VT_DISPATCH, pweb.ptr)
}

GUID(sGUID) <em>; 转换字符串为二进制的 GUID 并返回其缓冲.</em>
{
    GUID := BufferAlloc(16, 0)
    if DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", GUID) &lt; 0
        throw Exception("Invalid parameter #1", -1, sGUID)
    return GUID
}
</pre>
</div>

</body>
</html>